package com.xbongbong.saas.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.FieldAttrEntityExt;
import com.xbongbong.paas.help.FormExplainHelp;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.IdNamePropertyPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataGetDTO;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CalendarUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonDataUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.marketManage.pojo.dto.RelationSaleClueListDTO;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.DetailTabBusinessProductEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RelativeProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.MarketActivityThroughEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.WorkReportDailyEnum;
import com.xbongbong.saas.enums.business.WorkReportFieldEnum;
import com.xbongbong.saas.enums.dictionary.ClueStatusEnum;
import com.xbongbong.saas.model.CustomerStageLogModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.InstockModel;
import com.xbongbong.saas.model.OpportunityStageLogModel;
import com.xbongbong.saas.model.SaleStageModel;
import com.xbongbong.saas.model.WorkReportModel;
import com.xbongbong.saas.service.ContactService;
import com.xbongbong.saas.service.ContractPerformanceService;
import com.xbongbong.saas.service.InstockService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.SupplierContactService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.saas.toolbox.help.TimeUtil;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static java.util.stream.Collectors.toList;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;


/**
 * @author 吴峰
 * @version v1.0
 * @date 2019/2/20 10:59
 * @since v1.0
 */
@Component
public class SaasGetHelp extends BaseHelp {

    private static final Logger LOG = LoggerFactory.getLogger(SaasGetHelp.class);

    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private InstockService instockService;
    @Resource
    private InstockModel instockModel;
    @Resource
    private UserModel userModel;
    @Resource
    private FormExplainHelp formExplainHelp;
    @Resource
    private ContractPerformanceService contractPerformanceService;
    @Resource
    private CustomerStageLogModel customerStageLogModel;
    @Resource
    private OpportunityStageLogModel opportunityStageLogModel;
    @Resource
    private ProductService productService;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private ContactService contactService;
    @Resource
    private SupplierContactService supplierContactService;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private WorkReportModel workReportModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private SaleStageModel saleStageModel;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private DetailTabDataPermissionHelp detailTabDataPermissionHelp;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;

    /**
     * 编辑时saas特殊返回字段，放在一个对象中
     *
     * @param formDataGetVO
     * @param formDataGetDTO
     * @param data
     * @author chaoxiong.lei
     * @Date 15:26 2019/2/18
     * @since
     * @return void
     **/
    public void formatSaasAttrToReturn(FormDataGetVO formDataGetVO, FormDataGetDTO formDataGetDTO, JSONObject data) throws XbbException{
        Integer businessType = formDataGetDTO.getBusinessType();
        if (formDataGetVO == null || businessType == null) {
            return;
        }
        String corpid = formDataGetDTO.getCorpid();
        String userId = formDataGetDTO.getUserId();
        RedundantTemplateTypeEnum templateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        JSONObject saasReturnObj = new JSONObject();
        switch (templateTypeEnum) {
            case PRODUCT:
                Boolean ixJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
                saasReturnObj.put("isJxcUse", ixJxcUse);
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case WORKREPORT:
                JSONArray reviewerArray;
                try {
                    reviewerArray = JSONArray.parseArray(data.getString(WorkReportFieldEnum.REVIEWER.getAttr()));
                    reviewerArray = reviewerArray == null ? new JSONArray() : reviewerArray;
                }catch (Exception e){
                    reviewerArray = new JSONArray();
                }
                Boolean needUpdate = true;
                for (Object obj : reviewerArray){
                    JSONObject json = (JSONObject) obj;
                    if (Objects.equals(json.getString("userId"), userId)){
                        needUpdate = false;
                        break;
                    }
                }
                if (needUpdate){
                    // 只有手机端会调用，pc端会先调用pro/v1/workReport/detail
                    UserEntity userEntity = userModel.getByKey(userId,corpid);
                    JSONObject json = new JSONObject();
                    json.put("userId",userEntity.getUserId());
                    json.put("name",userEntity.getName());
                    json.put("avatar",userEntity.getAvatar());
                    reviewerArray.add(json);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put(WorkReportFieldEnum.REVIEWER.getAttr(), reviewerArray.toJSONString());
                    // 更新时间使用数据里的时间
                    UpdateDataEntity updateData = ExplainUtil.getUpdateData(formDataGetDTO.getDataId(), jsonObject, corpid, data.getLong(FieldTypeEnum.UPDATETIME.getAlias()));
                    workReportModel.updateBatch(Collections.singletonList(updateData), corpid);
                }
                JSONArray unReadArray = new JSONArray();
                String ownerId = data.getJSONArray("ownerId").getString(0);
                //根据规则，获得所有批阅人
                UserEntity userEntity = userModel.getByKey(ownerId, corpid);
                Integer type = data.getInteger(WorkReportFieldEnum.TYPE.getAttr());
                List<IdNamePropertyPojo> approvedPeopleList  = pushHelper.getApprovedPeopleList(userEntity,type);
                List<String> unReadUserIds = pushHelper.getPushUserIdListFromApprovedPeople(userEntity, approvedPeopleList);
                //获得抄送人
                JSONArray CCArray = data.getJSONArray(WorkReportDailyEnum.CC.getAttr());
                for (int i=0; i<CCArray.size(); i++){
                    unReadUserIds.add(CCArray.getJSONObject(i).getString("id"));
                }
                List<UserEntity> userEntityList = new ArrayList<>();
                if (CollectionsUtil.isNotEmpty(unReadUserIds)){
                    userEntityList = userModel.findEntitysByUserIds(unReadUserIds, corpid);
                }
                //已读人员Id
                List<String> readList = new ArrayList<>();
                for (int i=0; i<reviewerArray.size(); i++){
                    JSONObject readObject = reviewerArray.getJSONObject(i);
                    readList.add(readObject.getString("userId"));
                }
                //过滤已读人员
                userEntityList.forEach(user -> {
                    if (!readList.contains(user.getUserId())){
                        JSONObject unReadObject = new JSONObject();
                        unReadObject.put("userId", user.getUserId());
                        unReadObject.put("name", user.getName());
                        unReadObject.put("avatar", user.getAvatar());
                        unReadArray.add(unReadObject);
                    }
                });
                saasReturnObj.put("unRead", unReadArray);
                saasReturnObj.put(WorkReportDailyEnum.REVIEWER.getAttr(), reviewerArray);
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case PAY_SHEET:
                Double amount = getDoubleOrDefaultFromFormData(data, PaySheetEnum.AMOUNT.getAttr(), 0D);
                saasReturnObj.put(PaySheetEnum.AMOUNT.getSaasAttr(), amount);
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case PAYMENT_SHEET:
                Double payMoney = getDoubleOrDefaultFromFormData(data, PaymentSheetEnum.AMOUNT.getAttr(), 0D);
                saasReturnObj.put(PaySheetEnum.AMOUNT.getSaasAttr(), payMoney);
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case CONTRACT:
                Boolean isOpenDistribution = contractPerformanceService.openDistribution(corpid);
                saasReturnObj.put(CompanyConfigEnum.CONTRACT_PERFORMANCE_RULE_SET.getAlias(), isOpenDistribution);
                //快捷新建跟进记录tab栏显示与否
                saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case REFUND:
                Boolean isOpen = contractPerformanceService.openDistribution(corpid);
                saasReturnObj.put(CompanyConfigEnum.CONTRACT_PERFORMANCE_RULE_SET.getAlias(), isOpen);
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case CUSTOMER:
                //快捷新建跟进记录tab栏显示与否
                saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //客户动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case CLUE:
                //快捷新建跟进记录tab栏显示与否
                saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case CONTACT:
                //快捷新建跟进记录tab栏显示与否
                saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case SALES_OPPORTUNITY:
                //快捷新建跟进记录tab栏显示与否
                saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case SUPPLIER:
                //快捷新建跟进记录tab栏显示与否
                saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case PURCHASE:
                //快捷新建跟进记录tab栏显示与否
                saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case DISTRIBUTOR_MANAGEMENT:
                //快捷新建跟进记录tab栏显示与否
                // saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DISTRIBUTOR_DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            case DISTRIBUTOR_CONTACT:
                //快捷新建跟进记录tab栏显示与否
                // saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
                //动态显示与否
                saasReturnObj.put(StringConstant.DYNAMIC, true);
                //动态名称
                saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.DYNAMIC));
                formDataGetVO.setSaasObj(saasReturnObj);
                break;
            default:
                break;
        }
    }

    /**
     * 详情页基本信息特殊方法
     *
     * @param formDataGetVO
     * @param formDataGetDTO
     * @param data
     * @throws XbbException
     * @author long.rao
     * @date 2019-07-31 16:06
     */
    public void getSpecialMethod(FormDataGetVO formDataGetVO, FormDataGetDTO formDataGetDTO, JSONObject data) throws XbbException{
        Integer businessType = formDataGetDTO.getBusinessType();
        if (formDataGetVO == null || businessType == null) {
            return;
        }
        RedundantTemplateTypeEnum templateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        switch (templateTypeEnum) {
            case CUSTOMER:
                List<FieldAttrEntity> headList = formDataGetVO.getHeadList();
                String connectTimeStr = CustomerManagementEnum.LAST_CONNECT_TIME.getAttr();
                for (FieldAttrEntity attrEntity : headList) {
                    if (Objects.equals(attrEntity.getAttr(), connectTimeStr)) {
                        Long lastConnectTime = FastJsonHelper.getLongOrDefaultFromFormData(data, connectTimeStr, 0L);
                        data.put(connectTimeStr, TimeUtil.analysisLastConnectTime(lastConnectTime));
                        break;
                    }
                }
                break;
            default:
                break;
        }
    }

    /**
     * 将数据库中的两个字段转换成json对象格式给前端显示
     *
     * @param result     前端传回的data数据
     * @param attr       要格式化的字段attr
     * @param linkedAttr 格式化字段对应的隐藏字段
     * @author chaoxiong.lei
     * @date 15:38 2019/1/21
     * @since v1.0
     **/
    public void formatLinkBusiness4Show(JSONObject result, String attr, String linkedAttr) throws XbbException {
        if (result == null || attr == null || linkedAttr == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        JSONArray jsonArray = new JSONArray();
        try {
            // 获取关联业务的id
            String businessIdStr = result.getString(attr);
            // 获取关联业务的名称
            String businessNameStr = result.getString(linkedAttr);
            if (StringUtil.isNotEmpty(businessIdStr) && StringUtil.isNotEmpty(businessNameStr)) {
                // 关联业务不是必填，所以可能没有值
                String[] businessIdArr = businessIdStr.split(StringConstant.COMMA);
                String[] businessNameArr = businessNameStr.split(StringConstant.COMMA);
                for (int i = 0; i < businessIdArr.length; i++) {
                    Long businessId = Long.valueOf(businessIdArr[i]);
                    String businessName = businessNameArr[i];

                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, businessId);
                    jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, businessName);
                    jsonArray.add(jsonObject);
                }
                result.put(attr, jsonArray);
                result.put(linkedAttr, null);
            }
        } catch (Exception e) {
            // 类型转换异常或数组下标越界
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }

    }
    /**
     * 将数据库中的生日三个字段转换成json对象格式给前端显示
     *
     * @param result     前端传回的data数据
     * @param attr       要格式化的字段attr
     * @param birthdayLinkedAttr 公历生日字段对应的隐藏字段
     * @param lunarBirthdayLinkedAttr 农历生日字段对应的隐藏字段
     * @author chaoxiong.lei
     * @date 15:38 2019/1/21
     * @since v1.0
     **/
    public void formatBirthday4Show(JSONObject result, String attr, String birthdayLinkedAttr, String lunarBirthdayLinkedAttr) throws XbbException {
        if (result == null || attr == null || birthdayLinkedAttr == null || lunarBirthdayLinkedAttr == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        try {
            // 获取生日是公历还是阴历
            Integer isLunarBirthdayShown = result.getInteger(attr);
            JSONObject jsonObject = new JSONObject();
            if (Objects.equals(isLunarBirthdayShown, 1)) {
                // 阴历生日
                jsonObject.put(StringConstant.IS_LUNAR_BIRTHDAY_SHOWN, isLunarBirthdayShown);
                String lunarBirthdayStr = result.getString(lunarBirthdayLinkedAttr);
                jsonObject.put(StringConstant.LUNAR_BIRTHDAY, lunarBirthdayStr);
                jsonObject.put("value", CalendarUtil.lunar2Str(lunarBirthdayStr));
            } else if (Objects.equals(isLunarBirthdayShown, 0)) {
                // 公历生日
                jsonObject.put(StringConstant.IS_LUNAR_BIRTHDAY_SHOWN, isLunarBirthdayShown);
                Long birthday = result.getLong(birthdayLinkedAttr);
                jsonObject.put(StringConstant.BIRTHDAY, birthday);
                jsonObject.put("value", DateUtil.getString(birthday, DateUtil.SDFDate));
            }
            result.put(attr, jsonObject);
            result.put(birthdayLinkedAttr, null);
            result.put(lunarBirthdayLinkedAttr, null);
        } catch (Exception e) {
            // 类型转换异常
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }

    }

    /**
     * 获取String类型的数据
     * 返回可能为null，获取之后需要进行非null判断
     *
     * @param data 表单数据
     * @param attr 要获取数据的key值
     * @throws XbbException 类型转换失败异常
     * @author chaoxiong.lei
     * @date 14:09 2019/1/23
     * @since v1.0
     **/
    public String getStringFromFormData(JSONObject data, String attr) throws XbbException {
        return JsonDataUtil.getStringFromFormData(data, attr);
    }

    /**
     * 获取Integer类型的数据
     * 返回可能为null，获取之后需要进行非null判断
     *
     * @param data 表单数据
     * @param attr 要获取数据的key值
     * @throws XbbException 类型转换失败异常
     * @author chaoxiong.lei
     * @Date 14:09 2019/1/23
     * @since v1.0
     **/
    public Integer getIntegerFromFormData(JSONObject data, String attr) throws XbbException {
        Integer result = null;
        if (data == null || attr == null) {
            return result;
        }
        try {
            return data.getInteger(attr);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }


    /**
     * 获取Double类型的数据
     * 返回可能为null，获取之后需要进行非null判断
     *
     * @param data 表单数据
     * @param attr 要获取数据的key值
     * @throws XbbException 类型转换失败异常
     * @author chaoxiong.lei
     * @Date 14:09 2019/1/23
     * @since v1.0
     **/
    public Double getDoubleFromFormData(JSONObject data, String attr) throws XbbException {
        Double result = null;
        if (data == null || attr == null) {
            return result;
        }
        try {
            return data.getDouble(attr);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }

    /**
     * 获取JSONObject类型的数据
     * 返回可能为null，获取之后需要进行非null判断
     *
     * @param data 表单数据
     * @param attr 要获取数据的key值
     * @throws XbbException 类型转换失败异常
     * @author chaoxiong.lei
     * @Date 14:09 2019/1/23
     * @since v1.0
     **/
    public JSONObject getJsonObjectFromFormData(JSONObject data, String attr) throws XbbException {
        JSONObject result = null;
        if (data == null || attr == null) {
            return result;
        }
        try {
            return data.getJSONObject(attr);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }


    /**
     * 获取JSONArray类型的数据
     * 返回可能为null，获取之后需要进行非null判断
     *
     * @param data 表单数据
     * @param attr 要获取数据的key值
     * @throws XbbException 类型转换失败异常
     * @author chaoxiong.lei
     * @Date 14:09 2019/1/23
     * @since v1.0
     **/
    public JSONArray getJsonArrFromFormData(JSONObject data, String attr) throws XbbException {
        if (data == null || attr == null) {
            return null;
        }
        try {
            return data.getJSONArray(attr);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }

    /**
     * 获取Long类型的数据
     *
     * @param data 表单数据
     * @param attr 要获取数据的key值
     * @throws XbbException 类型转换失败异常
     * @author feng.zheng
     * @Date 19:19 2019/1/23
     * @since v1.0
     **/
    public Long getLongFromFormData(JSONObject data, String attr) throws XbbException {
        if (data == null || attr == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        try {
            if (data.get(attr) == null) {
                return null;
            }
            return data.getLong(attr);
        } catch (ClassCastException e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015);
        }
    }

    /**
     * saas特殊字段格式化
     *
     * @param saasAnalysisDataDTO 数据对象
     * @throws XbbException 抛出业务异常
     * @author haibin.zhang
     */
    @Override
    public void formatData(SaasAnalysisDataDTO saasAnalysisDataDTO, JSONObject result) throws XbbException {
        Integer businessType = saasAnalysisDataDTO.getBusinessType();
        if (businessType == null || businessType == 0) {
            LOG.error("businessType为空");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        RedundantTemplateTypeEnum templateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        switch (templateTypeEnum) {
            case PRODUCT:
                productService.getFormatData(saasAnalysisDataDTO, result);
                break;
            case CONTACT:
                contactService.getFormatData(saasAnalysisDataDTO, result);
                break;
            case CUSTOMER:
                break;
            case SUPPLIER_CONTACT:
                supplierContactService.getFormatData(saasAnalysisDataDTO, result);
                break;
            default:
                super.formatData(saasAnalysisDataDTO, result);
                break;


        }
    }

    /**
     * saas编辑时给解释字段赋初始值,格式化
     *
     * @param formatExplainDTO 表单解释格式化入参
     * @throws XbbException 抛出业务异常
     * @author long.rao
     * @date 2019-02-13 20:58
     */
    public void formatExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        Integer businessType = formatExplainDTO.getBusinessType();
        if (businessType == null || businessType == 0) {
            LOG.error("businessType为空");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        RedundantTemplateTypeEnum templateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        switch (templateTypeEnum) {
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                instockService.formatGetExplain(formatExplainDTO);
                instockModel.formatUpdateExplain(formatExplainDTO);
                break;
            case PRODUCT:
                // 产品编辑时如果是多规格，则成本和单价字段不显示
                productService.formatSpecialUpdateExplain(formatExplainDTO);
                productService.formatAddWarehouseToExplain(formatExplainDTO);
                break;
            default:
                formExplainHelp.formatExplain(formatExplainDTO, null);
                break;
        }
    }

    /**
     * 获取关联产品的表头
     *
     * @param xbbRefTypeEnum 业务枚举
     * @
     * @param corpid 公司id
     * @param attr 选择产品控件的attr
     * @author chaoxiong.lei
     * @date 14:50 2019/3/20
     * @since v1.0
     * @return java.util.List<FieldAttrEntity> 产品解释表头
     **/
    public List<FieldAttrEntityExt> getSelectProductExplains(XbbRefTypeEnum xbbRefTypeEnum, Integer targetCode, String corpid, String attr) throws XbbException {
        // 用于存放当前启用的产品模板解释的map
        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, FieldAttrEntity> nowStockProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        explainHelp.getRelativeProductExplainsFromDB(corpid, nowProductExplainMap, nowStockProductExplainMap);

        // 获取关联产品需要展示的字段
        DetailTabBusinessProductEnum businessProductEnum = DetailTabBusinessProductEnum.getByCode(xbbRefTypeEnum.getCode(), targetCode);
        List<FieldAttrEntity> relativeProductExplains = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (businessProductEnum != DetailTabBusinessProductEnum.UNKNOW) {
            List<RelativeProductEnum> businessProductEnumList = new ArrayList<>(businessProductEnum.getList());
            relativeProductExplains = explainHelp.getRelativeProductExplainList(businessProductEnumList,nowProductExplainMap, nowStockProductExplainMap,
                    xbbRefTypeEnum, attr);
        }

        int showSalePrice = 1;
        if (Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.OUTSTOCK) && Objects.equals(targetCode, XbbRefTypeEnum.CONTRACT.getCode())) {
            FormConfigEntity formConfigEntity = formConfigModel.getEntityByBusinessType(corpid, xbbRefTypeEnum.getCode(), FormConfigEnum.OUTSTOCK_DISPLAY_SALE_PRICE.getConfig());
            if (Objects.nonNull(formConfigEntity) && Objects.equals(formConfigEntity.getConfigValue(), FormConfigEnum.OUTSTOCK_DISPLAY_SALE_PRICE.getConfigValue())) {
                showSalePrice = 0;
            } else {
                showSalePrice = Integer.parseInt(FormConfigEnum.OUTSTOCK_DISPLAY_SALE_PRICE.getConfigValue());
            }
        }

        List<FieldAttrEntityExt> resultList = new ArrayList<>();
        for (FieldAttrEntity fieldAttrEntity : relativeProductExplains) {
            FieldAttrEntityExt fieldAttrEntityExt = new FieldAttrEntityExt();
            BeanUtil.copyProperties(fieldAttrEntity, fieldAttrEntityExt);
            String fieldAttr = fieldAttrEntity.getAttr();
            if (Objects.equals(fieldAttr, RelativeProductEnum.SALE_PRODUCT_PRICE.getSaasAttr()) || Objects.equals(fieldAttr, RelativeProductEnum.SALE_SUBTOTAL.getSaasAttr())
                    || Objects.equals(fieldAttr, RelativeProductEnum.PRODUCT_PRICE.getSaasAttr()) || Objects.equals(fieldAttr, RelativeProductEnum.SALE_DISCOUNT.getSaasAttr())) {
                fieldAttrEntityExt.setShowSalePrice(showSalePrice);
            }
            resultList.add(fieldAttrEntityExt);
        }

        return resultList;
    }


    /**
     * 打印模板，获取关联产品的表头
     * @param xbbRefTypeEnum 业务枚举
     * @param corpid 公司id
     * @param attr 关联字段
     * @return 字段解释列表
     * @throws XbbException xbb异常
     */
    public List<FieldAttrEntityExt> getSelectProductExplainsForPrint(XbbRefTypeEnum xbbRefTypeEnum, String corpid, String attr) throws XbbException {
        // 用于存放当前启用的产品模板解释的map
        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, FieldAttrEntity> nowStockProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        explainHelp.getRelativeProductExplainsFromDB(corpid, nowProductExplainMap, nowStockProductExplainMap);

        List<DetailTabBusinessProductEnum> list = DetailTabBusinessProductEnum.getListByCode(xbbRefTypeEnum.getCode());
        // 获取关联产品需要展示的字段
        List<RelativeProductEnum> businessProductEnumList = new ArrayList<>();
        for (DetailTabBusinessProductEnum detailTabBusinessProductEnum : list) {
            List<RelativeProductEnum> thisProductEnumList = detailTabBusinessProductEnum.getList();
            if (businessProductEnumList.isEmpty()) {
                businessProductEnumList.addAll(thisProductEnumList);
                continue;
            }
            for (RelativeProductEnum relativeProductEnum : thisProductEnumList) {
                if (!businessProductEnumList.contains(relativeProductEnum)) {
                    businessProductEnumList.add(relativeProductEnum);
                }
            }
        }
        List<FieldAttrEntity> relativeProductExplains = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!businessProductEnumList.isEmpty()) {
            relativeProductExplains = explainHelp.getRelativeProductExplainList(businessProductEnumList,nowProductExplainMap, nowStockProductExplainMap,
                    xbbRefTypeEnum, attr);
        }

        List<FieldAttrEntityExt> fieldAttrEntityExtList = new ArrayList<>();
        for (FieldAttrEntity fieldAttrEntity : relativeProductExplains) {
            FieldAttrEntityExt fieldAttrEntityExt = new FieldAttrEntityExt();
            BeanUtil.copyProperties(fieldAttrEntity, fieldAttrEntityExt);
            fieldAttrEntityExtList.add(fieldAttrEntityExt);
        }
//        if (Objects.equals(xbbRefTypeEnum.getCode(), XbbRefTypeEnum.INVENTORY.getCode())) {
//            // fix：12421 【web-盘点单】产品信息tab页中：盘亏数量显示错误
//            // fix：16652 【盘点单】盘点打印库存数量展示不正确
//            fieldAttrEntityExtList.removeIf(fieldAttr -> Objects.equals(fieldAttr.getAttr(), RelativeProductEnum.STOCK.getSaasAttr()));
//        }
        return fieldAttrEntityExtList;
    }

    /**
     * saas的摘要
     * @param summaryList
     * @param businessType
     * @param paasFormDataEntityExt
     * @return
     * @throws XbbException
     */
    public void getSaasSummary(List<SummaryDataPoJo> summaryList, Integer businessType, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException{

        JSONObject dataList = paasFormDataEntityExt.getData();
        String corpid = paasFormDataEntityExt.getCorpid();
        Long dataId = paasFormDataEntityExt.getId();
        RedundantTemplateTypeEnum templateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        switch (templateTypeEnum) {
            case CUSTOMER:
                String cStayTimeStr = customerStageLogModel.getAverageStayTime(corpid, dataId, paasFormDataEntityExt.getFormId());
                if (Objects.nonNull(cStayTimeStr)) {
                    SummaryDataPoJo summaryDataPoJo = new SummaryDataPoJo();
                    summaryDataPoJo.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.STAY_LONG_TIME));
                    summaryDataPoJo.setValue(Arrays.asList(cStayTimeStr));
                    summaryList.add(summaryDataPoJo);
                }
                break;
            case SALES_OPPORTUNITY:
                String opStayTimeStr = opportunityStageLogModel.getAverageStayTime(corpid, dataId, paasFormDataEntityExt.getFormId());
                if (Objects.nonNull(opStayTimeStr)) {
                    SummaryDataPoJo opSummaryData = new SummaryDataPoJo();
                    opSummaryData.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.STAY_LONG_TIME));
                    opSummaryData.setValue(Arrays.asList(opStayTimeStr));
                    summaryList.add(opSummaryData);
                }
                break;
                default:
                    break;
        }
    }

    /**
     * 市场活动详情页获取，关联"销售线索"的分页数据
     * @param relationSaleClueListDTO
     * @return
     * @throws XbbException
     */
    public XbbAggregatedPage getRelationSaleClueList(RelationSaleClueListDTO relationSaleClueListDTO) throws XbbException{
        String corpid = relationSaleClueListDTO.getCorpid();
        UserVO loginUser = relationSaleClueListDTO.getLoginUser();
        Integer page = relationSaleClueListDTO.getPage();
        Integer pageSize = relationSaleClueListDTO.getPageSize();
        Long formId = relationSaleClueListDTO.getFormId();

        //查询条件封装(角色权限+表单权限)
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", 0));
        //boolQueryBuilder.filter(termQuery(ClueEnum.getEsAttr4Keyword(ClueEnum.MARKET_ACTIVITY_ID),relationSaleClueListDTO.getDataId()));
        boolQueryBuilder.filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        fillConditionList(relationSaleClueListDTO);
        EsUtil.parseCondition(boolQueryBuilder, relationSaleClueListDTO.getConditions(), null, corpid, relationSaleClueListDTO.getBusinessType());
        //表单权限分装（formId条件）
        List<Long> formIds = setFormPermission(loginUser, boolQueryBuilder);
        //数据权限封装
        List<String> userIds = detailTabDataPermissionHelp.detailTeamBoolQueryParamPermission(boolQueryBuilder, corpid, formId, relationSaleClueListDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode(), loginUser, IndexTypeEnum.IDX_SAAS_CLUE_TEAM);
        // 共享权限处理
        saasListDataPermissionHelp.parseSharePermissionBoolQueryForUserId(boolQueryBuilder, formIds, userIds, loginUser, XbbRefTypeEnum.CLUE.getCode());


        //分页查询
        XbbAggregatedPage entitys = esHelper.findByPage(IndexTypeEnum.IDX_SAAS_CLUE, boolQueryBuilder, PaasFormDataEntityExt.class, null, page, pageSize, Collections.singletonList(new FieldSortBuilder(StringConstant.ADD_TIME).order(SortOrder.DESC)));
        return entitys;
    }

    /**
     * 市场活动关联的线索数据处理
     * @param formDataEsList
     */
    public void analysisClueDataList(List<PaasFormDataEntityExt> formDataEsList , RelationSaleClueListDTO relationSaleClueListDTO) throws XbbException {
        if(CollectionsUtil.isNotEmpty(formDataEsList)){
            String corpid = relationSaleClueListDTO.getCorpid();
            //团队处理
            List<Long> dataIdList = formDataEsList.stream().map(item -> item.getId()).collect(toList());
            List<Long> formIdList = formDataEsList.stream().map(item -> item.getFormId()).distinct().collect(toList());
            Set<String> creatorIds = formDataEsList.stream().map(item -> item.getCreatorId()).collect(Collectors.toSet());

            //获取主负责人团队
            List<UserTeamEntity> mainUserTeamList = userTeamHelp.getUserTeamList(dataIdList, corpid, XbbRefTypeEnum.CLUE.getCode(), false, 1);
            //创建人
            List<UserEntity> creatorUserList = new ArrayList<>();
            if(CollectionsUtil.isNotEmpty(creatorIds)){
                creatorUserList = userModel.findEntitysByUserIds(new ArrayList<>(creatorIds), corpid);
            }
//            //协同团队
//            Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//            Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//            userTeamService.getUserIdMap(Collections.singletonList(paasFormDataEntityExt.getDataId()),corpid,businessType,false,mainUserMap,coUserMap);

            //userId 和 userName 组成的map
            Map<String, String> createIdAndNameMap = getCreateIdAndNameMap(creatorUserList);
            //dataId 和 userName 组成的map(公海池的是没有的，负责人显示 -- )
            Map<Long, String> mainIdAndNameMap = getMainIdAndNameMap(mainUserTeamList);
            //查询线索数据对应的 表单模板
            Map<Long, Map<String, FieldAttrEntity>> fieldMap = getFieldMapByIdIn(corpid,formIdList);
            //声明变量： ture:隐藏；false：不隐藏 字段在展示的时候是否隐藏（根据字段的可见性来的）
            Boolean companyNameHide;
            Boolean clueStatusHide;
            Boolean ownerIdHide;
            Boolean creatorIdHide;
            Boolean addTimeHide;
            Boolean lastConnectTimeHide;
            HandlerExplainDTO handlerExplainDTO;
            for (PaasFormDataEntityExt paasFormDataEsEntity: formDataEsList){

                //线索状态
                JSONObject data = paasFormDataEsEntity.getData();
                if(data != null){
                    handlerExplainDTO = new HandlerExplainDTO();
                    BeanUtil.copyProperties(relationSaleClueListDTO, handlerExplainDTO);
                    handlerExplainDTO.setCreatorId(paasFormDataEsEntity.getCreatorId());
                    handlerExplainDTO.setOwnerId(Arrays.asList(paasFormDataEsEntity.getOwnerId()));
                    //handlerExplainDTO.setCoUserId(Arrays.asList(paasFormDataEsEntity.));
                    Map<String, FieldAttrEntity> fieldAttrEntityMap = fieldMap.getOrDefault(paasFormDataEsEntity.getFormId(), new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
                    companyNameHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.COMPANY_NAME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                    clueStatusHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.CLUE_STATUS.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                    ownerIdHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.OWNER_ID.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                    creatorIdHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.CREATOR_ID.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                    addTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.ADD_TIME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);
                    lastConnectTimeHide = ExplainUtil.isFieldNeedHide(fieldAttrEntityMap.getOrDefault(ClueEnum.LAST_CONNECT_TIME.getAttr(), new FieldAttrEntity()), handlerExplainDTO);

                    //线索名称(如果不需要隐藏的话，就不需要处理直接渲染)
                    if(companyNameHide){
                        data.put(ClueEnum.COMPANY_NAME.getAttr(),"");
                    }
                    //线索状态
                    String  code = data.getString(ClueEnum.CLUE_STATUS.getAttr());
                    ClueStatusEnum cluestatusenum = ClueStatusEnum.getByCode(code);
                    String  cluestatusString = (cluestatusenum == null || clueStatusHide) ? "":cluestatusenum.getName();
                    data.put(ClueEnum.CLUE_STATUS.getAttr(),cluestatusString);

                    String createName = createIdAndNameMap.get(paasFormDataEsEntity.getCreatorId());
                    //创建人
                    paasFormDataEsEntity.setCreatorId(creatorIdHide ? "": createName);
                    paasFormDataEsEntity.getData().put("creatorId",createName);
                    //负责人
                    String mainName = mainIdAndNameMap.get(paasFormDataEsEntity.getDataId());
                    paasFormDataEsEntity.setOwnerId(ownerIdHide ? "": mainName);
                    paasFormDataEsEntity.getData().put("ownerId",mainName);
                    //创建时间
                    paasFormDataEsEntity.getData().put("addTime", addTimeHide ? "":paasFormDataEsEntity.getAddTime());
                    //处理最后跟进时间(默认值 是 0 ，处理为空串，方便前端列表展示)
                    if((Objects.nonNull(data.get(ClueEnum.LAST_CONNECT_TIME.getAttr())) && ((Integer)data.get(ClueEnum.LAST_CONNECT_TIME.getAttr())).equals(0)) || lastConnectTimeHide){
                        data.put(ClueEnum.LAST_CONNECT_TIME.getAttr(),"");
                    }
                }
            }

        }

    }
    /**
     * 获取线索的多模板解释字段
     * @param formIdIn
     * @return
     * @throws XbbException
     */
    private Map<Long, Map<String, FieldAttrEntity>> getFieldMapByIdIn(String  corpid , List<Long> formIdIn) throws XbbException {
        Map<Long, Map<String, FieldAttrEntity>> fieldMap = new HashMap<>();
        Map<String, FieldAttrEntity> attrEntityMap;
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put("corpid", corpid);
        modelMap.put("idIn", formIdIn);
        modelMap.put("del", 0);
        List<PaasFormEntityExt> formEntityExts = paasFormModel.list(modelMap);
        if(CollectionsUtil.isEmpty(formEntityExts)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,  MessageConstant.FORM_NOT_EXIST);
        }
        for(PaasFormEntityExt paasFormEntityExt : formEntityExts) {
            PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(paasFormEntityExt.getId(), corpid);
            if(Objects.isNull(explainEntity)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            List<FieldAttrEntity> explainList = JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
            attrEntityMap = new HashMap<>(explainList.size());
            for (FieldAttrEntity field : explainList) {
                attrEntityMap.put(field.getAttr(), field);
            }
            fieldMap.put(paasFormEntityExt.getId(), attrEntityMap);
        }
        return fieldMap;
    }

    private Map<String ,String > getCreateIdAndNameMap(List<UserEntity> creatorUserList){
        Map<String ,String > result = new HashMap<>();
        if(CollectionsUtil.isNotEmpty(creatorUserList)){
            result= creatorUserList.stream().filter(userEntity->Objects.nonNull(userEntity.getUserId())).collect(Collectors.toMap(userEntity -> userEntity.getUserId().toString() , UserEntity::getName));
        }
        return result;
    }

    private Map<Long ,String > getMainIdAndNameMap(List<UserTeamEntity> mainUserTeamList){
        Map<Long ,String > result = new HashMap<>();
        if(CollectionsUtil.isNotEmpty(mainUserTeamList)){
            //dataId 作为 key, 一个key可能对应多个负责人,key重复时，value使用，拼接
            result = mainUserTeamList.stream().filter(item -> Objects.nonNull(item.getDataId())).collect(Collectors.toMap(UserTeamEntity::getDataId, UserTeamEntity::getUserName, (v1, v2) -> v1 + "," + v2));
        }
        return result;
    }

    /**
     * 设置表单权限
     * @param userVO
     * @param boolQueryBuilder
     */
    private List<Long> setFormPermission(UserVO userVO,BoolQueryBuilder boolQueryBuilder){
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", userVO.getCorpid());
        param.put("businessType", XbbRefTypeEnum.CLUE.getCode());
        param.put("enable", 1);
        param.put("del", DelEnum.NORMAL.getDel());
        List<PaasFormEntityExt> list = paasFormModel.list(param);
        Boolean noPermission;
        //获取用户有使用权限的表达 id集合
        List<Long> formIdIn = new ArrayList<>();
        if(CollectionsUtil.isNotEmpty(list)){
            for(PaasFormEntityExt paasFormEntityExt : list){
                List<OptionalRangeEntity> optionalRangeList = JSONObject.parseArray(paasFormEntityExt.getPermission(), OptionalRangeEntity.class);
                noPermission  = CollectionsUtil.isNotEmpty(optionalRangeList) && paasFormHelp.haveNoPermission(userVO, optionalRangeList);
                //去除没有使用权限的表单,noPermission为true  表示没有使用权限
                if (!noPermission) {
                    formIdIn.add(paasFormEntityExt.getId());
                }
            }
        }
        if(CollectionsUtil.isNotEmpty(formIdIn)){
            boolQueryBuilder.filter(termsQuery("formId",formIdIn));
        }else {
            //没有使用权限的表单 传输-1
            boolQueryBuilder.filter(termQuery("formId",-1));
        }
        return formIdIn;
    }

    private void fillConditionList(RelationSaleClueListDTO relationSaleClueListDTO){
        //关联市场活动
        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
        conditionsEntityExt.setAttr(ClueEnum.MARKET_ACTIVITY_ID.getAttr());
        conditionsEntityExt.setFieldType(ClueEnum.MARKET_ACTIVITY_ID.getFieldType());
        conditionsEntityExt.setName(ClueEnum.MARKET_ACTIVITY_ID.getAttrName());
        conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
        conditionsEntityExt.setValue(Collections.singletonList(relationSaleClueListDTO.getDataId()));
        relationSaleClueListDTO.getConditions().add(conditionsEntityExt);
        //穿透（转换为条件）
        Integer throughCode = relationSaleClueListDTO.getThroughCode();
        if(Objects.nonNull(throughCode) && throughCode > 0){
            ConditionsEntityExt clueStatueCondition = new ConditionsEntityExt();
            clueStatueCondition.setAttr(ClueEnum.CLUE_STATUS.getAttr());
            clueStatueCondition.setFieldType(ClueEnum.CLUE_STATUS.getFieldType());
            clueStatueCondition.setName(ClueEnum.CLUE_STATUS.getAttrName());
            MarketActivityThroughEnum marketActivityThroughEnum = MarketActivityThroughEnum.getByCode(throughCode);
            switch (marketActivityThroughEnum){
                case EFFECTIVE_CLUE:
                    clueStatueCondition.setSymbol(ConditionEnum.INCLUDE.getSymbol());
                    clueStatueCondition.setValue(ClueStatusEnum.getEffectiveClue());
                    relationSaleClueListDTO.getConditions().add(clueStatueCondition);
                    break;
                case TRANSFORMED_CLUE:
                    clueStatueCondition.setSymbol(ConditionEnum.EQUAL.getSymbol());
                    clueStatueCondition.setValue(Arrays.asList(ClueStatusEnum.TRANSFORMED.getCode()));
                    relationSaleClueListDTO.getConditions().add(clueStatueCondition);
                    break;
                case ALL_CLUE:
                default:
                    break;
            }

        }
    }
}

